﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ICRUDServices.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The service known types.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.ServiceModel;

    using ServiceLibrary.Services;
    using ServiceLibrary.Services.Dto;
    using ServiceLibrary.Services.Queries;
    using ServiceLibrary.Services.Results;
    using ServiceLibrary.Enums;

    /// <summary>
    /// The service known types.
    /// </summary>
    internal static class ServiceKnownTypes
    {
        #region Public Methods and Operators

        /// <summary>
        /// The get known command types.
        /// </summary>
        /// <param name="provider">
        /// The provider.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<Type> GetKnownCommandTypes(ICustomAttributeProvider provider)
        {
            return typeof(ServiceKnownTypes).Assembly.GetTypes().Where(t => typeof(ICommand).IsAssignableFrom(t));
        }

        /// <summary>
        /// The get known dto types.
        /// </summary>
        /// <param name="provider">
        /// The provider.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<Type> GetKnownDtoTypes(ICustomAttributeProvider provider)
        {
            IEnumerable<Type> types =
                typeof(ServiceKnownTypes).Assembly.GetTypes().Where(t => t.Namespace == typeof(User).Namespace);
            IEnumerable<Type> enumTypes =
                typeof(ServiceKnownTypes).Assembly.GetTypes().Where(t => t.Namespace == typeof(LogEntryType).Namespace);
            if (enumTypes.Any())
            {
                return types.Concat(enumTypes);
            }
            else
            {
                return types;
            }
        }

        /// <summary>
        /// The get known query types.
        /// </summary>
        /// <param name="provider">
        /// The provider.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/>.
        /// </returns>
        public static IEnumerable<Type> GetKnownQueryTypes(ICustomAttributeProvider provider)
        {
            return
                typeof(ServiceKnownTypes).Assembly.GetTypes()
                                         .Where(
                                             t =>
                                             typeof(IQuery).IsAssignableFrom(t) || typeof(IResult).IsAssignableFrom(t));
        }

        #endregion
    }

    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ICRUDServices" in both code and config file together.
    /// <summary>
    /// The CRUDServices interface.
    /// </summary>
    [ServiceContract(Name = "ICRUDServices")]
    [ServiceKnownType("GetKnownDtoTypes", typeof(ServiceKnownTypes))]
    public interface ICRUDServices
    {
        #region Public Methods and Operators

        /// <summary>
        /// The execute command.
        /// </summary>
        /// <param name="command">
        /// The command.
        /// </param>
        [OperationContract(Name = "ExecuteCommand")]
        [ServiceKnownType("GetKnownCommandTypes", typeof(ServiceKnownTypes))]
        void ExecuteCommand(ICommand command);

        /// <summary>
        /// The execute command.
        /// </summary>
        /// <param name="command">
        /// The command.
        /// </param>
        [OperationContract(Name = "ExecuteBatchsCommands")]
        [ServiceKnownType("GetKnownCommandTypes", typeof(ServiceKnownTypes))]
        void ExecuteBatchsCommands(List<ICommand> commands);

        /// <summary>
        /// The query.
        /// </summary>
        /// <param name="query">
        /// The query.
        /// </param>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        [OperationContract(Name = "Query")]
        [ServiceKnownType("GetKnownQueryTypes", typeof(ServiceKnownTypes))]
        IResult Query(IQuery query);

        #endregion
    }
}